import os, sys
import re
import socket
import IPy
import toml
import requests
from ping3 import ping
from time import sleep
from wmi import WMI
import pywifi
from pywifi import const, Profile

# 判断IP地址是否有效
def is_ip(address):
    try:
        ret = IPy.IP(address)
        print(ret)
        return True
    except Exception as e:
        return False

def is_ipv4(strIP):
    try:
        socket.inet_aton(strIP)
        return True
    except socket.error:
        return False

# 判断子网掩码是否有效
def is_valid_netmask(subnet_mask):
    # 将子网掩码转换为二进制字符串
    binary_mask = ''.join([bin(int(x))[2:].zfill(8) for x in subnet_mask.split('.')])
    # print(binary_mask)
    # 判断子网掩码是否连续为1，且后面全为0
    if not re.match(r'^1*0*$', binary_mask):
        return False
    return True
def Toml_read(toml_file):
    try:
        with open(toml_file, "r", encoding="utf-8-sig") as fs:
            t_data = toml.load(fs)
        return t_data
    except IOError as err:
        print("I/O error({0})".format(err))
        return {}

def is_online():
    headers = {'User-Agent': 'Mozilla/5.0',
               'Content-Type': 'text/html; charset=utf-8'
               }
    try:
        x = requests.get('https://baidu.com', verify=True, headers=headers, timeout=5)
        if x.status_code==200:
            return True
        else:
            return False
    except Exception as e:
        return False

def is_alive(ip):
    return ping(ip, timeout=5)


def scan_wifi(dst_wifi):
    result = False
    wifi = pywifi.PyWiFi()
    # for w in wifi.interfaces():
    #     print(w.name())
    iface = wifi.interfaces()[0]
    iface.scan()
    sleep(1)
    basewifi = iface.scan_results()
    for i in basewifi:
        if i.ssid == dst_wifi:
            # print('wifi扫描结果:{}'.format(i.ssid))
            result = True
            break
    return result


def connect_wifi():
    wifi = pywifi.PyWiFi()  # 创建一个wifi对象
    ifaces = wifi.interfaces()[0]  # 取第一个无限网卡
    print(ifaces.name())  # 输出无线网卡名称
    ifaces.disconnect()  # 断开网卡连接
    sleep(3)  # 缓冲3秒
    profile = Profile()  # 配置文件
    profile.ssid = "DWK-Mi10S"  # wifi名称
    profile.auth = const.AUTH_ALG_OPEN  # 需要密码
    profile.akm.append(const.AKM_TYPE_WPA2PSK)  # 加密类型
    profile.cipher = const.CIPHER_TYPE_CCMP  # 加密单元
    profile.key = 'dongweikang'  # wifi密码
    ifaces.remove_all_network_profiles()  # 删除其他配置文件
    tmp_profile = ifaces.add_network_profile(profile)  # 加载配置文件
    ifaces.connect(tmp_profile)  # 连接
    sleep(5)  # 5秒后检查连接状态
    if ifaces.status() == const.IFACE_CONNECTED:
        print("成功连接")
        return True
    else:
        print("失败")
        return False

class Eth_obj(object):
    def __init__(self):
        self.wmiservice = WMI()
        self.configs = self.wmiservice.Win32_NetworkAdapterConfiguration()  # 获取到本地所有有网卡信息,list
        # self.configs = self.wmiservice.Win32_NetworkAdapterConfiguration(IPEnabled=True)  # 获取到本地所有有网卡信息,list
        # interface = c.Win32_NetworkAdapter(NetConnectionID=interface_name)[0]

    def refresh_configs(self):
        self.configs = self.wmiservice.Win32_NetworkAdapterConfiguration()

    def get_adapter_byname(self, name="以太网"):
        interfaces = self.wmiservice.Win32_NetworkAdapter(NetConnectionID=name)
        if interfaces:
            return interfaces[0]
        # for interface in interfaces:
        #     print(interface)
        #     print(interface.MACAddress)

    def get_all_ips(self):
        flag = 0
        # 遍历所有网卡，找到要修改的那个
        print(self.configs[1])
        for con in self.configs:
            print(con.MACAddress, con.Description, con.IPAddress, con.ServiceName)
    def get_adapter_bymac(self, mac_addr):
        flag = 0
        # 遍历所有网卡，找到要修改的那个
        for con in self.configs:
            mac = con.MACAddress
            if mac and mac == mac_addr:
                return con
    def enable_adapter(self, adapter):
        adapter.Enable()

    def disable_adapter(self, adapter):
        adapter.Disable()

    def set_dhcp(self, adapter):
        ret1 = adapter.EnableDHCP()
        # ret2 = adapter.ReleaseDHCPLease()
        ret3 = adapter.RenewDHCPLease()
        return [ret1, ret3]

    def update_ip(self, adapter, ip, subnetmask, gateway=None, dns=None, Metric=50):
        if ip and subnetmask:
            if not is_ipv4(ip):
                print('IP地址不合法')
                return False
            # print(is_valid_netmask(subnetmask))
            if is_valid_netmask(subnetmask) == 0:
                print('子网掩码不合法')
                return False
            # 开始执行修改ip、子网掩码、网关
            ipres = adapter.EnableStatic(IPAddress=[ip], SubnetMask=[subnetmask])
            if ipres[0] == 0:
                print('设置IP成功')
            else:
                if ipres[0] == 1:
                    print('设置IP成功，需要重启计算机！')
                else:
                    print('修改IP失败')
                    return False
        # 修改网关
        if gateway:
            wayres = adapter.SetGateways(DefaultIPGateway=[gateway], GatewayCostMetric=[Metric])
            if wayres[0] == 0:
                print('设置网关成功')
            else:
                print('修改网关失败')
                return False
        else:
            wayres = adapter.SetGateways(DefaultIPGateway=[ip])
        # 修改dns
        if dns and type(dns) is list:
            dnsres = adapter.SetDNSServerSearchOrder(DNSServerSearchOrder=dns)
            if dnsres[0] == 0:
                print('设置DNS成功,等待3秒刷新缓存')
                sleep(3)
                # 刷新DNS缓存使DNS生效
                os.system('ipconfig /flushdns')
            else:
                print('修改DNS失败')
                return False
        return True

if __name__ == '__main__':
    # print(scan_wifi("DWK-Mi10S"))
    # sys.exit(0)
    ethobj = Eth_obj()
    config = Toml_read("config.toml")
    online_status = False
    secondary_active = False
    primary_adapter_name = config['primary']['adapter_name']
    secondary_adapter_name = config['secondary']['adapter_name']
    secondary_adapter_ip = config['secondary']['adapter_ip']
    primary_adapter = ethobj.get_adapter_byname(primary_adapter_name)
    secondary_adapter = ethobj.get_adapter_byname(secondary_adapter_name)
    print("主网卡状态：{},备网卡状态：{}".format(primary_adapter.NetEnabled, secondary_adapter.NetEnabled))
    if is_online():
        online_status = True
        if primary_adapter and primary_adapter.NetEnabled:
            print(f'当前通过主网卡：“{primary_adapter_name}“ 正常')
        elif secondary_adapter and secondary_adapter.NetEnabled:
            print(f'当前通过备网卡：”{secondary_adapter_name}“ 正常')
            secondary_active = True
        else:
            print(f'当前通过其他网卡可以正常访问互联网')
    if primary_adapter and primary_adapter.NetEnabled:
        pri_adapter = ethobj.get_adapter_bymac(primary_adapter.MACAddress)
        print(pri_adapter)
        if pri_adapter.DefaultIPGateway and pri_adapter.DefaultIPGateway[0] != '0.0.0.0':
            if is_alive(pri_adapter.DefaultIPGateway[0]):
                if is_online():
                    online_status = True
                    print(f'主网卡：“{primary_adapter_name}“ 可以正常访问互联网')
        else:
            print(f'主网卡：“{primary_adapter_name}“ 默认网关不存在')
    if not online_status:
        if secondary_adapter:
            if not secondary_adapter.NetEnabled:
                ethobj.enable_adapter(secondary_adapter)
            sec_adapter = ethobj.get_adapter_bymac(secondary_adapter.MACAddress)
            if sec_adapter and config['secondary']['adapter_method'].lower() == "static":
                ret = ethobj.update_ip(sec_adapter, config['secondary']['adapter_ip'], config['secondary']['adapter_netmask'], config['secondary']['adapter_gw'], config['secondary']['adapter_dns'])
                if ret:
                    print(f"设置备网卡“{secondary_adapter_name}” IP地址完成，等待3秒")
                    sleep(3)
                    sec_adapter_new = ethobj.get_adapter_bymac(secondary_adapter.MACAddress)
                    if sec_adapter_new.IPAddress[0] == config['secondary']['adapter_ip']:
                        if is_alive(secondary_adapter_ip):
                            if not is_online():
                                print(f"通过备网卡{secondary_adapter_name}并设置IP {config['secondary']['adapter_ip']} 访问互联网失败")
                        else:
                            print(f'备网卡：“{secondary_adapter_name}“ 可以正常访问互联网')
                    else:
                        print(f'备网卡：“{secondary_adapter_name}“ 的IP地址未生效')
                else:
                    print(f"启用备网卡：“{secondary_adapter_name}“ 并设置IP失败")
    if secondary_active:
        print(f"切换主网卡“{primary_adapter_name}” 连接互联网")
        if primary_adapter:
            if not primary_adapter.NetEnabled:
                ethobj.enable_adapter(primary_adapter)
            ethobj.refresh_configs()
            pri_adapter = ethobj.get_adapter_bymac(primary_adapter.MACAddress)
            # pri_adapter.RenewDHCPLease()
            if config['primary']['adapter_method'].lower() == "dhcp":
                pass
                ret = ethobj.set_dhcp(pri_adapter)
                # if ret[-1]:
            if config['primary']['adapter_type'] == "WLAN":
                if scan_wifi("DWK-Mi10S"):
                    connect_wifi()
                    print(f"设置主网卡“{primary_adapter_name}” 完成，等待检测退出")
                    has_get_gw = False
                    while not has_get_gw:
                        ethobj.refresh_configs()
                        pri_adapter = ethobj.get_adapter_bymac(primary_adapter.MACAddress)
                        pri_adapter_gw = pri_adapter.DefaultIPGateway
                        if pri_adapter_gw and is_alive(pri_adapter_gw[0]):
                            print(f"主网卡：“{primary_adapter_name}“默认网关：{pri_adapter_gw[0]}")
                            print(f'主网卡：“{primary_adapter_name}“ 可以正常访问互联网')
                            has_get_gw = True
                        sleep(3)
                else:
                    print(f"设置主网卡“{primary_adapter_name}” 要连接的目标WIFI不在连接范围，退出")
    # is_online()
    # is_alive('192.168.0.1')
    # ethobj = Eth_obj()
    # ethobj.get_all_ips()
    # dst_adapter = ethobj.get_adapter("74:86:E2:31:33:A9")
    # adapter = ethobj.get_adapter_byname('WLAN')
    # print(adapter)
    # if adapter and adapter.NetEnabled:
    #     ethobj.disable_adapter(adapter)
    # else:
    #     ethobj.enable_adapter(adapter)
    # if adapter:
    #     if not adapter.NetEnabled:
    #         ethobj.enable_adapter(adapter)
    #     dst_adapter = ethobj.get_adapter_bymac(adapter.MACAddress)
    #     if dst_adapter:
    #         ethobj.update_ip(dst_adapter, '192.168.0.48', '255.255.255.0')
